# coding: utf-8

# -------------------------------------------------------------------------------
# Name:         testsuite_set.py
# Description:  
# Author:       XiangjunZhao
# EMAIL:        2419352654@qq.com
# Date:         2020/12/22 下午10:02
# -------------------------------------------------------------------------------
from io import BytesIO

import pandas as pd
from django.http import StreamingHttpResponse
from rest_framework import status
from rest_framework.generics import DestroyAPIView
from rest_framework.mixins import UpdateModelMixin
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ReadOnlyModelViewSet, GenericViewSet

from QAPlatform.mixins import CustomCreateModelMixin
from apps.BasicAuthService.models import Role
from apps.CeleryScheduledTaskService.HttpAutoTestService.testsuite_set_task import batch_exec_testsuite_set
from apps.HttpAutoTestService.filters import TestsuiteSetFilter
from apps.HttpAutoTestService.models import TestsuiteSet, TestsuiteSet2Testsuite
from apps.HttpAutoTestService.serializers import TestsuiteSetListSerializer, TestsuiteSetSerializer
from apps.HttpAutoTestService.utils.export_testsuite_task import export_testsuite
from utils.common import get_version

__all__ = ['TestsuiteSetListViewSet', 'TestsuiteSetViewSet', 'TestsuiteSetBatchDestroyAPIView',
           'TestsuiteSetBatchExecAPIView', 'TestsuiteSetExportAPIView']


class TestsuiteSetListViewSet(ReadOnlyModelViewSet):
    """
    场景集列表
    """
    serializer_class = TestsuiteSetListSerializer
    filter_class = TestsuiteSetFilter

    def get_queryset(self):
        user = self.request.user
        testsuite_sets = TestsuiteSet.objects.filter(is_deleted=False)
        if not Role.objects.filter(code='SUPERADMIN', user=user, is_deleted=False):
            testsuite_sets = testsuite_sets.filter(project__members=user).distinct()
        return testsuite_sets


class TestsuiteSetViewSet(CustomCreateModelMixin, UpdateModelMixin, GenericViewSet):
    """
    场景集创建、更新
    """
    queryset = TestsuiteSet.objects.filter(is_deleted=False)
    serializer_class = TestsuiteSetSerializer


class TestsuiteSetBatchDestroyAPIView(DestroyAPIView):
    """
    场景集批量删除
    """

    def delete(self, request, *args, **kwargs):
        testsuite_sets = request.data.get('testsuite_sets')
        # 1、删除场景集
        TestsuiteSet.objects.filter(id__in=testsuite_sets).update(is_deleted=True)
        # 2、解绑与场景的关联
        TestsuiteSet2Testsuite.objects.filter(testsuite_set_id__in=testsuite_sets).delete()

        return Response(status=status.HTTP_204_NO_CONTENT)


class TestsuiteSetBatchExecAPIView(APIView):
    """
    场景集批量执行
    """

    def post(self, request, *args, **kwargs):
        user = request.user
        data = request.data
        testsuite_sets = data.get('testsuite_sets')
        version = get_version()
        # 以异步方式执行
        batch_exec_testsuite_set.delay(testsuite_sets=testsuite_sets, executor_id=user.id, is_periodictask=False,
                                       version=version)
        # 以阻塞方式执行
        # batch_exec_testsuite_set(testsuite_sets=testsuite_sets, executor_id=user.id, is_periodictask=False, version=version)
        return Response(status=status.HTTP_200_OK, data='程序正在后台运行中,请稍后查看结果……', content_type='application/json')


class TestsuiteSetExportAPIView(APIView):
    """
    导出测试场景集
    """

    def post(self, request, *args, **kwargs):
        data = request.data
        testsuite_set_ids = data.get('testsuite_set_ids')
        testsuite_set_list = TestsuiteSet.objects.filter(id__in=testsuite_set_ids, is_deleted=False)
        bio = BytesIO()
        with pd.ExcelWriter(bio, engine='xlsxwriter') as excel_writer:
            current_sheet_index = 0
            for testsuite_set in testsuite_set_list:
                testsuite_set_name = testsuite_set.name
                testsuite_set2testsuite_list = testsuite_set.testsuite_set2testsuite.all()
                for testsuite_set2testsuite in testsuite_set2testsuite_list:
                    current_sheet_index += 1
                    testsuite = testsuite_set2testsuite.testsuite
                    project_name = testsuite.project.name
                    testsuite_name = testsuite.name
                    summary_info = f'项目名称：{project_name}\n场景集名称：{testsuite_set_name}\n场景名称：{testsuite_name}\n说明：如果需要将此导出数据再次导入系统中，请删除此行数据，再在接口列表中通过【导入接口|用例】功能导入'
                    # excel的sheet页名称最多31个字符
                    sheet_name = f'Sheet{current_sheet_index}'
                    # 导出场景用例数据
                    export_testsuite(excel_writer=excel_writer, sheet_name=sheet_name, testsuite=testsuite, start_row=1)
                    # 填充场景概要信息
                    sheet = excel_writer.sheets[sheet_name]
                    sheet.merge_range(first_row=0, first_col=0, last_row=0, last_col=9, data=summary_info)
                    sheet.set_row(row=0, height=65)
            excel_writer.save()
            excel_writer.close()
        bio.seek(0)
        response = StreamingHttpResponse(bio)
        response['Content-Type'] = 'application/octet-stream'
        response['Content-Disposition'] = 'attachment;filename="测试场景集导出.xlsx"'
        return response
